package de.bazinga.rotw.gameModes;

import java.util.Random;
import java.util.Vector;

import com.captiveimagination.jgn.clientserver.JGNClient;
import com.captiveimagination.jgn.clientserver.JGNServer;
import com.jme.math.Vector3f;
import com.jme.scene.Node;
import com.jmex.game.state.GameStateManager;

import de.bazinga.rotw.base.attacker.AttackerCreateMessage;
import de.bazinga.rotw.base.attacker.AttackerList;
import de.bazinga.rotw.base.attacker.AttackerUpdateMessage;
import de.bazinga.rotw.base.attacker.BaseAttacker;
import de.bazinga.rotw.game.RotwGameState;
import de.bazinga.rotw.network.Server;
import de.bazinga.rotw.statistics.OnlineStatistics;

public class DefendYourBase implements GameMode{

	/**
	 * The Base for the Mode "DefendOurBase"
	 */
	private Node baseStation = null;
	/**
	 * The Start-Locations for the Attackers
	 */
	private Vector<Vector3f> baseAttackerStartLocations = new Vector<Vector3f>();
	
	/**
	 * When did we add the last Attacker
	 */
	private long lastAttacker = 0;
	
	/**
	 * How long until we add a new Attacker
	 */
	private int attackerLag = 5000;
	
	
	@Override
	public void gameUpdate() {
		RotwGameState game = ((RotwGameState)GameStateManager.getInstance().getChild("gameState"));
		
		
		if(game.isServer() &&  (System.currentTimeMillis() - lastAttacker) > attackerLag) {
			// Add new Attacker
			BaseAttacker att = AttackerList.getUnusedAttacker();
			att.updateRenderState();
			att.reset();
			game.getRootNode().attachChild(att);
			att.updateRenderState();
			att.updateGeometricState(0, false);
			
			AttackerList.addAttacker(att);
			
			lastAttacker = System.currentTimeMillis();
			
			AttackerCreateMessage attMsg = new AttackerCreateMessage();
			attMsg.setAttackerId(att.getAttackerId());
			attMsg.setLocation(att.getLocalTranslation());
			((Server)game.getSyncManager()).getServer().sendToAll(attMsg);
		}
		
		// Check for dead Attackers
		if(AttackerList.getDeadAttackers() != null && AttackerList.getDeadAttackers().size() != 0) {
			Vector<BaseAttacker> delete = new Vector<BaseAttacker>();
			for(BaseAttacker att:AttackerList.getDeadAttackers()) {
				if(att.resetAfterDeath()) {
					delete.add(att);
				}
			}
			
			for(BaseAttacker att:delete) {
				AttackerList.removeDeadAttacker(att);
			}
		}
	}

	@Override
	public void initClient(JGNClient client) {
		AttackerUpdateMessage attMsg = new AttackerUpdateMessage();
    	attMsg.setRequestUpdate(true);
    	client.sendToServer(attMsg);
	}

	@Override
	public void initServer(JGNServer server) {}

	@Override
	public void playerUpdate() {}

	@Override
	public void playerAction() {}
	

	@Override
	public void reset() {
		for(int i=0;i<10;i++) {
			BaseAttacker att = AttackerList.getUnusedAttacker();
			att.setUnused();
		}
		
		OnlineStatistics.defendStarted = System.currentTimeMillis();
	}
	

	@Override
	public boolean useTeams() {
		return false;
	}
	
	
	
	


	public void setBaseStation(Node baseStation) {
		this.baseStation = baseStation;
	}




	public Node getBaseStation() {
		return baseStation;
	}


	public Vector<Vector3f> getBaseAttackerStartLocations() {
		return baseAttackerStartLocations;
	}
	
	public Vector3f getRandomAttackerStartLocation() {
		return baseAttackerStartLocations.get(new Random().nextInt(baseAttackerStartLocations.size()));
	}
	
	
	public void decreaseAttackerLag(int decr) {
		attackerLag -= decr;
		
		if(attackerLag < 2000) {
			attackerLag = 2000;
		}
	}
	
	public void resetAttackerLag() {
		attackerLag = 5000;
	}
}